<template>
  <div>
    <el-dialog
      class="app-attachment-dialog"
      :title="title ? title : '选择文件'"
      :visible.sync="dialogVisible"
      :close-on-click-modal="false"
      :width="simple?'20%':'70%'"
      top="3vh"
      append-to-body
      @opened="dialogOpened"
    >
      <template v-if="simple">
        <app-upload
          v-loading="uploading"
          class="app-attachment-simple-upload"
          :disabled="uploading"
          :multiple="true"
          :max="10"
          :params="uploadParams"
          :fields="uploadFields"
          :accept="accept"
          @start="handleStart"
          @success="handleSuccess"
          @complete="handleComplete"
        >
          <div v-if="uploading">{{ uploadCompleteFilesNum }}/{{ uploadFilesNum }}</div>
          <i v-else class="el-icon-upload"/>
        </app-upload>
      </template>
      <template v-else>
        <el-card>
          <el-row>
            <el-col :span="6">
              <div class="left-side">
                <el-button size="small" type="primary" @click="showAddGroup(-1)">
                  添加分组
                </el-button>
                <el-input
                  v-model="keyword"
                  style="width:90%; margin: 15px 0;"
                  size="small"
                  placeholder="请输入分类名称搜索"
                />
                <el-menu
                  v-loading="groupListLoading"
                  class="group-menu"
                  mode="vertical"
                  :default-active="groupActive"
                  :active="groupActive"
                >
                  <el-menu-item index="all" @click="switchGroup(-1)">
                    <i class="el-icon-tickets"/>
                    <span>全部</span>
                  </el-menu-item>
                  <template v-for="(item, index) in groupItem">
                    <el-menu-item :index="'' + index" @click="switchGroup(index)">
                      <div style="display: flex; justify-content: space-between">
                        <div style="overflow: hidden;text-overflow: ellipsis">
                          <i class="el-icon-tickets"/>
                          <span>{{ item.title }}</span>
                        </div>
                        <div style="display: flex">
                          <el-button type="text" @click.stop="showAddGroup(index)">编辑</el-button>
                          <div style="color:#409EFF;margin:0 2px">|</div>
                          <el-button type="text" @click.stop="deleteGroup(index)">删除</el-button>
                        </div>
                      </div>
                    </el-menu-item>
                  </template>
                </el-menu>
              </div>

            </el-col>
            <el-col :span="18">
              <div v-loading="loading" class="right-side">
                <div class="search" style="margin-right: 12px; display: flex;">
                  <el-input
                    v-model="p_keyword"
                    placeholder="请输入名称搜索"
                    clearable
                    class="input-with-select"
                    size="small"
                    style="margin-right: 10px; width: 300px"
                    @keyup.enter.native="picSearch"
                  />
                  <el-button size="small" type="primary" @click="picSearch">查询</el-button>

                  <div style="margin-left: 20px;">
                    <el-button v-if="!showEditBlock" size="small" @click="showEditBlock=true">开启编辑</el-button>
                    <template v-if="showEditBlock">
                      <el-button size="small" style="margin-right: 12px" @click="showEditBlock=false">退出编辑模式
                      </el-button>
                      <el-checkbox
                        v-model="selectAll"
                        border
                        size="small"
                        label="全选"
                        style="margin-right: 12px;margin-bottom: 0"
                        @change="selectAllChange"
                      />
                      <el-button
                        size="small"
                        :loading="deleteLoading"
                        style="margin-right: 12px"
                        @click="deleteItems"
                      >删除
                      </el-button>
                      <el-dropdown
                        v-loading="moveLoading"
                        size="small"
                        trigger="click"
                        :split-button="true"
                        @command="moveItems"
                      >
                        <span>移动至</span>
                        <el-dropdown-menu slot="dropdown">
                          <el-dropdown-item
                            v-for="(item, index) in groupList"
                            :key="index"
                            :command="index"
                          >
                            {{ item.title }}
                          </el-dropdown-item>
                        </el-dropdown-menu>
                      </el-dropdown>
                    </template>
                  </div>

                </div>
                <div class=" app-attachment-upload">
                  <app-upload
                    v-loading="uploading"
                    :disabled="uploading"
                    :multiple="true"
                    :max="10"
                    :params="uploadParams"
                    :fields="uploadFields"
                    :accept="accept"
                    flex="main:center cross:center"
                    style="width: 100px;height: 100px"
                    @start="handleStart"
                    @success="handleSuccess"
                    @complete="handleComplete"
                  >
                    <div v-if="uploading">{{ uploadCompleteFilesNum }}/{{ uploadFilesNum }}</div>
                    <i v-else class="el-icon-upload"/>
                  </app-upload>
                </div>
                <el-row :gutter="16" class="file-list">

                  <el-col v-for="(item, index) in attachments" :key="index" :span="4" class="file-item">
                    <el-tooltip
                      class="item"
                      effect="dark"
                      :content="item.name"
                      placement="top"
                      :open-delay="1"
                    >
                      <div
                        :key="index"
                        :class="'app-attachment-item '+((item.checked&&!showEditBlock)?' checked':'')+(item.selected&&showEditBlock?' selected':'')"
                        @click="handleClick(item)"
                      >
                        <img
                          class="app-attachment-img"
                          :src="item.preview_url"
                          style="width: 100px;height: 100px;"
                        >
                        <div
                          v-if="item.file_type == 'video'"
                          class="app-attachment-img"
                          style="width: 100px;height: 100px;position: relative"
                        >
                          <div
                            v-if="item.cover"
                            class="app-attachment-video-cover"
                            :style="'background-image: url('+item.cover+');'"
                          />
                          <video
                            :id="'app_attachment_'+ _uid + '_' + index"
                            style="width: 0;height: 0;visibility: hidden;"
                          >
                            <source :src="item.full_url">
                          </video>
                          <div class="app-attachment-video-info">
                            <i class="el-icon-video-play"/>
                            <span>{{ item.duration ? item.duration : '&#45;&#45;:&#45;&#45;' }}</span>
                          </div>
                        </div>
                        <div
                          v-if="item.file_type == 'file'"
                          class="app-attachment-img"
                          style="width: 100px;height: 100px;line-height: 100px;text-align: center"
                        >
                          <i class="file-type-icon el-icon-document"/>
                        </div>
                        <div class="app-attachment-name">{{ item.name }}</div>
                        <i v-if="item.checked" class="app-attachment-active-icon el-icon-circle-check"/>
                      </div>
                    </el-tooltip>
                  </el-col>
                </el-row>
                <div style="padding: 5px;text-align: right;margin-top: 20px">
                  <el-pagination
                    v-if="pagination"
                    background
                    :current-page.sync="page"
                    :page-size="pagination.pageSize"
                    layout="prev, pager, next, jumper"
                    :total="pagination.totalCount"
                    @size-change="handleLoadMore"
                    @current-change="handleLoadMore"
                  />
                </div>
              </div>

            </el-col>
          </el-row>

          <div style="text-align: right">
            <span v-if="showEditBlock" style="color: #909399">请先退出编辑模式</span>
            <el-button type="primary" :disabled="showEditBlock" @click="confirm">选定</el-button>
          </div>
        </el-card>
      </template>
    </el-dialog>
    <el-dialog
      append-to-body
      title="分组管理"
      :visible.sync="addGroupVisible"
      :close-on-click-modal="false"
      width="25%"
    >
      <el-form
        ref="groupForm"
        label-width="80px"
        :model="groupForm"
        :rules="groupFormRule"
        @submit.native.prevent
      >
        <el-form-item label="分组名称" prop="title" style="margin-bottom: 22px;">
          <el-input v-model="groupForm.title" maxlength="8" show-word-limit/>
        </el-form-item>
        <el-form-item style="text-align: right">
          <el-button type="primary" :loading="groupFormLoading" @click="groupFormSubmit('groupForm')">保存
          </el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
    <div
      style="line-height: normal;"
      :style="'display:'+(display?display:'inline-block')"
      @click="dialogVisible = !dialogVisible"
    >
      <slot/>
    </div>
  </div>
</template>

<script>
import AppUpload from '@/components/UploadFile/Upload'

import * as GroupApi from '@/api/upload_group'
import * as FileApi from '@/api/upload_file'

export default {
  name: 'UploadFile',
  components: {
    AppUpload
  },
  props: {
    display: String,
    title: String,
    multiple: Boolean,
    max: Number,
    params: Object,
    simple: {
      type: Boolean,
      value: false
    },
    type: {
      type: String,
      default: 'image'
    },
    value: {
      type: String,
      default: ''
    },
    openDialog: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      groupActive: 'all',
      canvas: null,
      uploading: false,
      dialogVisible: false,
      loading: true,
      loadingMore: false,
      noMore: false,
      attachments: [],
      checkedAttachments: [],
      uploadParams: {},
      uploadFields: {},
      uploadCompleteFilesNum: 0,
      uploadFilesNum: 0,
      page: 1,
      addGroupVisible: false,
      noMall: true,
      groupList: [],
      groupItem: [],
      groupListLoading: false,
      groupForm: {
        id: null,
        title: ''
      },
      groupFormRule: {
        title: [
          { required: true, message: '请填写分组名称。' }
        ]
      },
      groupFormLoading: false,
      showEditBlock: false,
      selectAll: false,
      deleteLoading: false,
      moveLoading: false,
      currentAttachmentGroupId: null,
      video: null,
      keyword: '',
      pagination: {
        pageSize:16,
        totalCount:0
      },
      p_keyword: ''
    }
  },
  computed: {
    accept: {
      get() {
        if (this.type === 'image') {
          return 'image/*'
        }
        if (this.type === 'video') {
          return 'video/*'
        }
        return '*/*'
      }
    }
  },
  watch: {
    openDialog(newVal, oldVal) {
      this.dialogVisible = newVal
    },
    dialogVisible(newVal, oldVal) {
      if (!newVal) {
        this.$emit('closed')
      }
    },
    keyword(newVal, oldVal) {
      const groupList = this.groupList
      const arr = []
      groupList.map(v => {
        if (v.title.indexOf(newVal) !== -1) {
          arr.push(v)
        }
      })
      this.groupItem = arr
    }
  },
  created() {
  },
  methods: {
    show() {
      this.dialogVisible = true
    },
    picSearch() {
      this.page = 1
      this.loading = true
      this.loadGroups()
      this.loadList()
    },

    dialogOpened() {
      if (this.simple) {
        return
      }
      if (!this.attachments || !this.attachments.length) {
        this.loading = true
        this.loadGroups()
        this.loadList()
      }
    },
    deleteItems() {
      const itemIds = []
      for (const i in this.attachments) {
        if (this.attachments[i].selected) {
          itemIds.push(this.attachments[i].id)
        }
      }
      if (!itemIds.length) {
        this.$message.warning('请先选择需要删除的图片。')
        return
      }
      const that = this
      this.$confirm('确认删除所选的' + itemIds.length + '张图片？', '提示', {
        type: 'warning'
      }).then(() => {
        that.deleteLoading = true
        FileApi.destroy({
          ids: itemIds
        }).then(res => {
          that.deleteLoading = false
          that.$message.success(res.data.message)
          for (const i in itemIds) {
            for (const j in that.attachments) {
              if (that.attachments[j].id === itemIds[i]) {
                that.attachments.splice(j, 1)
                break
              }
            }
          }
        }).catch(e => {
          that.deleteLoading = false
        })
      }).catch(() => {
      })
    },
    selectAllChange(value) {
      for (const i in this.attachments) {
        this.attachments[i].selected = value
      }
    },
    selectItem(item) {
      item.selected = !item.selected
    },
    moveItems(index) {
      console.log('el-tooltip item app-attachment-item selected')
      const itemIds = []
      for (const i in this.attachments) {
        if (this.attachments[i].selected) {
          itemIds.push(this.attachments[i].id)
        }
      }
      if (!itemIds.length) {
        this.$message.warning('请先选择需要移动的图片。')
        return
      }
      const that = this
      this.$confirm('确认移动所选的' + itemIds.length + '张图片？', '提示', {
        type: 'warning'
      }).then(() => {
        that.moveLoading = true
        FileApi.move({
          ids: itemIds,
          group_id: this.groupItem[index].id
        }).then(res => {
          that.moveLoading = false
          that.$message.success(res.data.message)
          that.switchGroup(index)
        }).catch(e => {
          that.moveLoading = false
        })
      }).catch(() => {
      })
    },
    loadGroups() {
      this.noMall = false
      this.groupItem = []
      this.groupList = []

      const that = this

      GroupApi.index({}).then(res => {
        that.groupItem = res.data
        that.groupList = res.data
      })
    },
    showAddGroup(index) {
      if (index > -1) {
        this.groupForm.id = this.groupItem[index].id
        this.groupForm.title = this.groupItem[index].title
      } else {
        this.groupForm.id = null
        this.groupForm.title = ''
      }
      this.groupForm.edit_index = index
      this.addGroupVisible = true
    },
    deleteGroup(index) {
      const that = this
      this.$confirm('是否删除分组？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        GroupApi.destroy(this.groupItem[index].id).then(res => {
          that.groupItem.splice(index, 1)
        })
      }).catch(() => {
      })
    },
    groupFormSubmit(formName) {
      const that = this
      this.$refs[formName].validate(valid => {
        if (valid) {
          this.groupFormLoading = true
          const id = this.groupForm.id
          if (id > 0) {
            GroupApi.update(id, Object.assign({}, this.groupForm)).then(res => {
              that.addGroupVisible = false
              that.groupFormLoading = false
              that.loadGroups()
            }).catch(e => {
              that.groupFormLoading = false
            })
          } else {
            GroupApi.store(Object.assign({}, this.groupForm)).then(res => {
              that.addGroupVisible = false
              that.groupFormLoading = false
              that.loadGroups()
            }).catch(e => {
              that.groupFormLoading = false
            })
          }
        }
      })
    },
    switchGroup(index) {
      this.attachments = []
      this.page = 1
      this.noMore = false
      this.loading = true
      this.uploadParams = {
        group_id: index > -1 ? this.groupItem[index].id : null
      }
      this.currentAttachmentGroupId = index > -1 ? this.groupItem[index].id : null
      this.groupActive = index > -1 ? '' + index : 'all'
      this.loadList()
    },
    loadList() {
      this.attachments = []
      const that = this
      FileApi.index({
        page: this.page,
        page_size: this.pagination.pageSize,
        group_id: this.currentAttachmentGroupId,
        keyword: this.p_keyword
      }).then(res => {
        //console.log('res', res.data.list)
        if (res.data.list.length <= 0) {
          //that.noMore = true
        }
        for (const i in res.data.data) {
          res.data.list[i].checked = false
          res.data.list[i].selected = false
          res.data.list[i].duration = null
        }
        that.attachments = res.data.list
        that.pagination.totalCount = res.data.total
        that.checkedAttachments = []
        that.loading = false
        that.loadingMore = false
        // this.updateVideo();
      }).catch(e => {
        that.groupFormLoading = false
      })
    },
    // 重新处理文件列表
    resetAttachments() {
      // 设置选中状态
      this.$nextTick(() => {
        for (const i in this.checkedAttachments) {
          for (const j in this.attachments) {
            this.attachments[j].checked = false
            if (this.attachments[j].id === this.checkedAttachments[i].id) {
              this.attachments[j].checked = true
              break
            }
          }
        }
      })

    },

    handleClick(item) {
      //console.log('click', item)
      if (this.showEditBlock) {
        this.selectItem(item)
        return
      }
      if (item.checked) {
        item.checked = false
        for (const i in this.checkedAttachments) {
          if (item.id === this.checkedAttachments[i].id) this.checkedAttachments.splice(i, 1)
        }
        this.resetAttachments()
        return
      }
      if (this.multiple) {
        let checkedCount = 0
        for (const i in this.attachments) if (this.attachments[i].checked) checkedCount++
        if (this.max && !item.checked && checkedCount >= this.max) return
        item.checked = true
        this.checkedAttachments.push(item)
        this.resetAttachments()
      } else {
        for (const i in this.attachments) this.attachments[i].checked = false
        item.checked = true
        this.checkedAttachments = [item]
        this.resetAttachments()
      }
    },
    confirm() {
      this.$emit('selected', this.checkedAttachments, this.params)
      this.dialogVisible = false
      const urls = []
      for (const i in this.checkedAttachments) {
        urls.push(this.checkedAttachments[i].full_url)
      }
      for (const i in this.attachments) {
        this.attachments[i].checked = false
      }
      this.checkedAttachments = []
      if (!urls.length) {
        return
      }
      if (this.multiple) {
        this.$emit('input', urls)
      } else {
        this.$emit('input', urls[0])
      }
    },
    handleStart(files) {
      this.uploading = true
      this.uploadFilesNum = files.length
      this.uploadCompleteFilesNum = 0
    },
    handleSuccess(file) {
      if (file.response && file.response.data && file.response.code === 0) {
        this.loadList()
        // this.updateVideo();
      }
    },
    handleComplete(files) {
      this.uploading = false
      if (this.simple) {
        const urls = []
        const attachments = []
        for (const i in files) {
          if (files[i].response.data && files[i].response.data.code === 0) {
            urls.push(files[i].response.data.full_url)
            attachments.push(...files[i].response.data)
          }
        }
        if (!urls.length) {
          return
        }
        this.dialogVisible = false
        this.$emit('selected', attachments, this.params)
        if (this.multiple) {
          this.$emit('input', urls)
        } else {
          this.$emit('input', urls[0])
        }
      }
    },
    handleLoadMore(currentPage) {
      if (this.noMore) {
        return
      }
      this.page = currentPage
      this.loading = true
      this.loadingMore = true
      this.loadList()
    },
    updateVideo() {
      if (!this.canvas) {
        this.canvas = document.getElementById('app-attachment-canvas')
      }
      for (const i in this.attachments) {
        if (this.attachments[i].type == 'video') {
          if (this.attachments[i].duration) {
            continue
          }
          let times = 0
          let video = null
          const maxRetry = 10
          const id = 'app_attachment_' + this._uid + '_' + i
          const timer = setInterval(() => {
            times++
            if (times >= maxRetry) {
              clearInterval(timer)
            }
            if (!video) {
              video = document.getElementById(id)
            }
            if (!video) {
              return
            }
            try {
              const zoom = 0.15
              this.canvas.width = video.videoWidth * zoom
              this.canvas.height = video.videoHeight * zoom
              this.canvas.getContext('2d').drawImage(video, 0, 0, this.canvas.width, this.canvas.height)
              this.attachments[i].cover_pic_src = this.canvas.toDataURL('image/jpg')
            } catch (e) {
              console.warn('获取视频封面异常: ', e)
            }

            if (video.duration && !isNaN(video.duration)) {
              let m = Math.trunc(video.duration / 60)
              let s = Math.trunc(video.duration) % 60
              m = m < 10 ? `0${m}` : `${m}`
              s = s < 10 ? `0${s}` : `${s}`
              this.attachments[i].duration = `${m}:${s}`
              clearInterval(timer)
            }
          }, 500)
        }
      }
    }
  }
}
</script>

<style scoped>
.right-side {
  margin: 15px;
}

.file-item {
  width: 120px;
  height: 120px;
  margin: 10px;
  margin-bottom: 30px;
  border: 1px solid #ebeef5;
  border-radius: 5px;
  position: relative;
  cursor: pointer;
}

.app-attachment-upload {
  box-shadow: none;
  border: 1px dashed #b2b6bd;
  width: 100px;
  margin: 18px 24px 0;
}

.app-attachment-upload i {
  font-size: 30px;
  color: #909399;
}


.app-attachment-dialog .app-attachment-name {
  color: #666666;
  font-size: 13px;
  word-break: break-all;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
  overflow: hidden;
}

.app-attachment-simple-upload {
  width: 100% !important;
  height: 120px;
  border: 1px dashed #e3e3e3;
  cursor: pointer;
}

.app-attachment-simple-upload:hover {
  background: rgba(0, 0, 0, .05);
}

.app-attachment-simple-upload i {
  font-size: 32px;
}

.app-attachment-upload {
  box-shadow: none;
  border: 1px dashed #b2b6bd;
  width: 100px;
  margin: 18px 24px 0;
}

.app-attachment-upload i {
  font-size: 30px;
  color: #909399;
}

.app-attachment-list {
  display: flex;
  height: 150px;
}

.app-attachment-item {
  position: relative;
  text-align: center;
  margin-bottom: 15px;
  display: flow-root;
}

.app-attachment-item.checked,
.app-attachment-item.selected {
  box-shadow: 0 0 0 1px #1ed0ff;
  background: #daf5ff;
  border-radius: 5px;
}

.app-attachment-dialog .app-attachment-name {
  color: #666666;
  font-size: 13px;
  word-break: break-all;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
  overflow: hidden;
}

.app-attachment-simple-upload {
  width: 100% !important;
  height: 120px;
  border: 1px dashed #e3e3e3;
  cursor: pointer;
}

.app-attachment-simple-upload:hover {
  background: rgba(0, 0, 0, .05);
}

.app-attachment-simple-upload i {
  font-size: 32px;
}

.el-menu-item.is-active {
  color: #409EFF;
}

</style>
